﻿using System;
using System.Collections;
using System.Collections.Generic;
using AdministradorGeneral.Seguridad;
using CapaDatos;
using Ext.Net;
using IU.Contabilidad;
using IU.Generico.Events;
using ModuloSoporte.Security;
using PhantomDb.Entidades;
using WebHelper;
using WebHelper.Controles;
using WebHelper.Controles.Interfaces;
using ModuloSoporte;

namespace IU.Generico
{
    public partial class ControlAbm : ControlGenerico, ITitulo, IDescriptible
    {
        /// <summary>
        /// Muestra u oculta la barra de filtros.
        /// </summary>
        public bool MostrarFiltros
        {
            get { return TopBarFiltros.Visible; }
            set { TopBarFiltros.Visible = value; }
        }

        /// <summary>
        /// Título del control.
        /// </summary>
        public String Titulo
        {
            get
            {
                return GridPanel1.Title;
            }

            set
            {
                GridPanel1.Title = value;
                LabelTitulo.Text = value;
            }
        }

        /// <summary>
        /// Descripción.
        /// </summary>
        public String Descripcion
        {
            get
            {
                return LabelDescrip.Text;
            }

            set
            {
                LabelDescrip.Text = value;
            }
        }

        private Permisos permisos = null;
        /// <summary>
        /// Permisos de acceso a datos.
        /// </summary>
        public Permisos Permisos
        {
            get { return permisos; }
            set { permisos = value; }
        }

        #region Eventos propios
        protected void CallAlActualizar()
        {
            if (AlActualizar != null)
            {
                AlActualizar.Invoke(this, EventArgs.Empty);
            }
        }

        protected void CallAlModificar(object tag, ref BeforeRecordUpdatedEventArgs e)
        {
            if (AlModificar != null)
            {
                var ev = new EventUpdateAbm(tag, ref e);
                AlModificar.Invoke(this, ev);
            }
        }

        protected void CallAlEliminar(object tag)
        {
            if (AlEliminar != null)
            {
                var ev = new EventDeleteAbm(tag);
                AlEliminar.Invoke(this, ev);
            }
        }

        public event EventHandler AlActualizar = null;
        public event EventHandler<EventInsertAbm> AlInsertar = null;
        public event EventHandler<EventAfterInsertAbm> AlDespuesInsertar = null;
        public event EventHandler<EventUpdateAbm> AlModificar = null;
        public event EventHandler<EventDeleteAbm> AlEliminar = null;

        /// <summary>
        /// Ejecuta el evento "AlInsertar".
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="e"></param>
        protected void CallAlInsertar(object tag, ref BeforeRecordInsertedEventArgs e)
        {
            if (AlInsertar != null)
            {
                EventInsertAbm ev = new EventInsertAbm(tag, ref e);
                AlInsertar.Invoke(this, ev);
            }
        }

        /// <summary>
        /// Ejecuta el evento "AlInsertar".
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="e"></param>
        protected void CallDespuesDeInsertar(object tag, ref AfterRecordInsertedEventArgs e)
        {
            if (AlDespuesInsertar != null)
            {
                EventAfterInsertAbm ev = new EventAfterInsertAbm(tag, ref e);
                AlDespuesInsertar.Invoke(this, ev);
            }
        }

        protected void AlDespuesInsertarRecord(ref AfterRecordInsertedEventArgs e)
        {
            // Seguridad
            IDictionary test = e.NewValues;
            var companies = new Dictionary<string, string>[1];
            companies[0] = new Dictionary<string, string>();

            try
            {
                foreach (object o in test.Keys)
                {
                    var value = test[o].ToString();
                    companies[0].Add(o.ToString(), value);
                }
            }
            catch
            {
            }

            // Evento al insertar
            if (AlDespuesInsertar != null)
            {
                object obj;
                try
                {
                    Storer st = new Storer(Tipo);
                    st.Valores = Valores;

                    obj = st.MakeObjectFromRow(companies);
                }
                catch (Exception ex)
                {
                    obj = null;
                    UIHelper.MostrarExcepcionSimple(ex, "Error");
                }
                CallDespuesDeInsertar(obj, ref e);
            }
        }


        /// <summary>
        /// Ejecuta el evento antes de insertar un registro en la base de datos.
        /// </summary>
        /// <param name="e"></param>
        protected void AlInsertarRecord(ref BeforeRecordInsertedEventArgs e)
        {
            // Seguridad
            IDictionary test = e.NewValues;
            var companies = new Dictionary<string, string>[1];
            companies[0] = new Dictionary<string, string>();

            try
            {
                foreach (object o in test.Keys)
                {
                    var value = test[o].ToString();
                    SQLInjection.AplicarSeguridad(ref value);
                    if (SQLInjection.IsSqlSentence(value))
                    {
                        throw new Exception("Uno de los valores ingresados no cumple con las reglas de seguridad del sistema. La operación será cancelada.");
                    }
                    else
                    {
                        companies[0].Add(o.ToString(), value);
                    }
                }
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error de seguridad");
                e.Cancel = true;
            }

            // Evento al insertar
            if (AlInsertar != null)
            {
                object obj;
                try
                {
                    Storer st = new Storer(Tipo);
                    st.Valores = Valores;

                    obj = st.MakeObjectFromRow(companies);
                }
                catch (Exception ex)
                {
                    obj = null;
                    UIHelper.MostrarExcepcionSimple(ex, "Error");
                }
                CallAlInsertar(obj, ref e);
            }
        }

        /// <summary>
        /// Ejecuta el evento antes de modificar un registro en la base de datos.
        /// </summary>
        /// <param name="e"></param>
        protected void AlModificarRecord(ref BeforeRecordUpdatedEventArgs e)
        {
            // Seguridad
            IDictionary test = e.NewValues;
            var companies = new Dictionary<string, string>[1];
            companies[0] = new Dictionary<string, string>();

            try
            {
                foreach (object o in test.Keys)
                {
                    var value = test[o].ToString();
                    SQLInjection.AplicarSeguridad(ref value);
                    if (SQLInjection.IsSqlSentence(value))
                    {
                        throw new Exception("Uno de los valores ingresados no cumple con las reglas de seguridad del sistema. La operación será cancelada.");
                    }
                    else
                    {
                        companies[0].Add(o.ToString(), value);
                    }
                }
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error de seguridad");
                e.Cancel = true;
            }

            // Evento al modificar
            if (AlModificar != null)
            {
                object obj;
                try
                {
                    Storer st = new Storer(Tipo);
                    st.Valores = Valores;

                    obj = st.MakeObjectFromRow(companies);
                }
                catch (Exception ex)
                {
                    obj = null;
                    UIHelper.MostrarExcepcionSimple(ex, "Error");
                }
                CallAlModificar(obj, ref e);
            }
        }

        /// <summary>
        /// Ejecuta el evento antes de eliminar un registro en la base de datos.
        /// </summary>
        /// <param name="e"></param>
        protected void AlEliminarRecord(ref BeforeRecordDeletedEventArgs e)
        {
            /*// Seguridad
            IDictionary test = e.Record;
            var companies = new Dictionary<string, string>[1];
            companies[0] = new Dictionary<string, string>();

            try
            {
                foreach (object o in test.Keys)
                {
                    var value = test[o].ToString();
                    SQLInjection.AplicarSeguridad(ref value);
                    if (SQLInjection.IsSqlSentence(value))
                    {
                        throw new Exception("Uno de los valores ingresados no cumple con las reglas de seguridad del sistema. La operación será cancelada.");
                    }
                    else
                    {
                        companies[0].Add(o.ToString(), value);
                    }
                }
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error de seguridad");
                e.Cancel = true;
            }

            // Evento al eliminar
            if (AlEliminar != null)
            {
                object obj;
                try
                {
                    Storer st = new Storer(Tipo);
                    st.Valores = Valores;

                    obj = st.MakeObjectFromRow(companies);
                }
                catch (Exception ex)
                {
                    obj = null;
                    UIHelper.MostrarExcepcionSimple(ex, "Error");
                }
                AlEliminar(obj, ref e);
            }*/
        }


        #endregion

        /// <summary>
        /// SqlValor aplicado a los combo boxes. [DEPRECATED]
        /// Usar ValoresRelacion. ValoresCombo dejado por temas de compatibilidad.
        /// </summary>
        public SqlValor[] ValoresCombo
        {
            get { return ValoresRelacion; }
            set { ValoresRelacion = value; }
        }

        #region Atributos de bases de datos

        private String select = "";
        public String Select
        {
            get { return select; }
            set { select = value; }
        }

        private String insert = "";
        public String Insert
        {
            get { return insert; }
            set { insert = value; }
        }

        private String update = "";
        public String Update
        {
            get { return update; }
            set { update = value; }
        }

        private String delete = "";
        public String Delete
        {
            get { return delete; }
            set { delete = value; }
        }

        #endregion

        protected void DeleteRow()
        {
            try
            {
                string json = Session["json"].ToString();
                Dictionary<string, string>[] companies = JSON.Deserialize<Dictionary<string, string>[]>(json);

                Storer st = new Storer(Tipo);
                st.Valores = Valores;
                CallAlEliminar(st.MakeObjectFromRow(companies));
                string consulta = st.MakeDeleteRow(companies);
                Datos.ConsultarEx(consulta);
            }
            catch { }
            Store1.WarningOnDirty = false; // Para que no muestre el mensaje de "you have uncomitted..."
            GridPanel1.Reload();
            Store1.WarningOnDirty = true;
        }

        protected void btnDelete_OnClick(object sender, DirectEventArgs e)
        {
            try
            {
                Session["json"] = e.ExtraParams["Values"];
                DeleteRow();
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error");
            }
        }

        protected void buttonFiltro_OnClick(object sender, DirectEventArgs e)
        {
            string name = comboBox1.Text;
            Atributos a = (new WebHelper.Storer(Tipo)).GetAtributosFromColumna(name);
            Storer st = new WebHelper.Storer(Tipo);
            string valor = Text.Text;
            GridFilter gf = Storer.GetFilter(GridFilters1, a.Nombre);

            try
            {
                switch (Storer.GetBasicType(a.Tipo))
                {
                    case WebHelper.Storer.BasicType.Number:
                        {
                            NumericFilter filtro = (NumericFilter)gf;
                            filtro.SetValue(Traductor.TraductorHelper.Parse(valor));
                        }
                        break;
                    case WebHelper.Storer.BasicType.Text:
                        {
                            StringFilter filtro = (StringFilter)gf;
                            filtro.SetValue(valor);
                        }
                        break;
                    case WebHelper.Storer.BasicType.Date:
                        {
                            DateFilter filtro = (DateFilter)gf;
                            filtro.SetValue(DateTime.Parse(valor));
                        }
                        break;
                    case WebHelper.Storer.BasicType.Bool:
                        {
                            BooleanFilter filtro = (BooleanFilter)gf;
                            filtro.SetValue(bool.Parse(valor));
                        }
                        break;
                }

                gf.SetActive(true);
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error");
            }
        }

        protected void buttonClean_OnClick(object sender, DirectEventArgs e)
        {
            foreach (GridFilter gf in GridFilters1.Filters)
            {
                gf.SetActive(false);
            }
        }

        public override void FantasmearControl(Storer st)
        {
            try
            {
                st.Valores = Valores;
                st.ValoresCombo = ValoresRelacion;

                if (Insert.Equals(""))
                    Insert = st.GetInsert();
                if (Select.Equals(""))
                    Select = st.GetSelect();
                if (Update.Equals(""))
                    Update = st.GetUpdate();
                if (Delete.Equals(""))
                    Delete = st.GetDelete();

                this.SqlDataSource1.ProviderName = "MySql.Data.MySqlClient";
                this.SqlDataSource1.ConnectionString = StringConnection;
                this.SqlDataSource1.InsertCommand = Insert;
                this.SqlDataSource1.SelectCommand = Select;
                this.SqlDataSource1.UpdateCommand = Update;
                this.SqlDataSource1.DeleteCommand = Delete;

                AplicarPermisos();

                st.ObjectToSqlDataSource(ref SqlDataSource1);
                st.ObjectToStore(ref Store1);
                st.ObjectToGridPanel(ref GridPanel1, Permisos.AMBloqueado);

                CargarFiltros(st);
            }
            catch (Exception ex)
            {
                UIHelper.MostrarExcepcionSimple(ex, "Error");
            }
        }

		
		public void AplicarPermisos()
        {
            /*// Permisos de la tabla
            if (Permisos == null)
            {
                if (!Global.Logueado)
                    Permisos = Permisos.PermisosGuest;
                else
                    Permisos = Logica.UseCases.Logueado.Administrador ? Permisos.PermisosAdmin : Permisos.PermisosGuest;
            }
            */

            // Permisos de la tabla
            if (Permisos == null)
            {

                if (!Global.Logueado)
                {
                    Permisos = Permisos.PermisosGuest;
                }
                else
                {
                    Permisos = ContabilidadGlobal.Admin.Permisos;//Permisos.PermisosAdmin;
                }
            }

            if (!Permisos.Alta)
            {
                this.btnInsert.Enabled = false;
                this.btnInsert.Hide();
                if (!Permisos.Modif)
                {
                    this.btnSave.Enabled = false;
                    this.btnSave.Hide();
                }
            }
            if (!Permisos.Baja)
            {
                this.btnDelete.Enabled = false;
                this.btnDelete.Hide();
            }
        }

        public void Reload()
        {
            GridPanel1.Reload();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        public void CargarFiltros(Storer st)
        {
            List<object[]> names = new List<object[]>();

            foreach (Atributos s in st.Armador.Atributos)
            {
                //Si no se definió una columna, o si se configuró una columna visible
                //entonces, agregamos el atributo.
                if (s.Columna == null)
                {
                    names.Add(new object[] { s.Nombre, s.Nombre });
                }
                else if (s.Columna.Visible)
                {
                    names.Add(new object[] { s.Nombre, s.Columna.Titulo });
                }
            }

            Store2.DataSource = names;
            Store2.DataBind();

            st.ObjectToFilters(ref this.GridFilters1);
        }


        [DirectMethod]
        public void ExcepcionValidacionDatos()
        {
            try
            {
                throw new Exception("Error en ingreso de datos, ingrese valores válidos en los datos");
            }
            catch (Exception e)
            {
                Ext.Net.ResourceManager.AjaxSuccess = false;
                Ext.Net.ResourceManager.AjaxErrorMessage = e.Message;
            }
        }
    }
}